package com.ease.util {

   /**
    * An IPv4 or IPv6 address.
    */
   public class IpAddress {

      /**
       * Constructs an IP address.
       *
       * @param bytes
       *       Byte array representation of the IP address.
       *       Should be a uint array which length is 4 for
       *       an IPv4 address or 16 for an IPv6 address.
       */
      public function IpAddress(bytes:Array) {
         if (bytes == null) {
            throw new ArgumentError("bytes");
         }
         if (bytes.length != 4 && bytes.length != 16) {
            throw new ArgumentError("bytes");
         }
         _bytes = bytes;
      }

      /**
       * Get the byte representation of the IP address.
       * This is an array of 4 bytes for an IPv4 address
       * or an array of 16 bytes for an IPv6 address.
       */
      public function get bytes():Array {
         return _bytes;
      }

      private var _bytes:Array;

      /**
       * Whether this is an IPv4 or IPv6 address.
       */
      public function get isIpv4():Boolean {
         return _bytes.length == 4;
      }

      /**
       * Whether this IP address is equal to another.
       *
       * @param other
       *       An IP address.
       * @return
       *       True if this IP address is equal to the other.
       */
      public function equals(other:IpAddress):Boolean {
         if (other == null) {
            return false;
         }
         var otherBytes:Array = other.bytes;
         if (_bytes.length != otherBytes.length) {
            return false;
         }
         for (var i:uint = 0; i < _bytes.length; ++i) {
            if (_bytes[i] != otherBytes[i]) {
               return false;
            }
         }
         return true;
      }

      /**
       * Determine if this IP address is less than another.
       *
       * @param other
       *       An IP address.
       * @return
       *       True if this IP address is less than the other IP address.
       *       Returns false if the other address is null or has
       *       another address family (IPv4, IPv6).
       */
      public function lessThan(other:IpAddress):Boolean {
         if (other == null) {
            return false;
         }
         var otherBytes:Array = other.bytes;
         if (_bytes.length != otherBytes.length) {
            return false;
         }
         for (var i:uint = 0; i < _bytes.length; ++i) {
            if (_bytes[i] == otherBytes[i]) {
               continue;
            }
            return _bytes[i] < otherBytes[i];
         }
         return false; // They are equal
      }

   } // class
} // package
